<?php


/**
 * Used to request social information from the container. This includes data for friends, profiles, app data, and activities. All apps that require access to people information should send a DataRequest to the container. {@link http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html opensocial.DataRequest (0.7) }
 * 
 * Remember that this object should only be used in the Action, and in the View you should use OSDataResponse instead. Anyway if you really need to access to this object in can pass it to the view.
 * Using OSDataRequest is as simple as creating the object, appending request's to it, and calling the "send()" function to generate the response. Here it's a sample code of how to get the viewers friends from the container:  
 * 
 * <code>
 * // this code is in the Action
 * $this->viewer_friends = new OSViewerFriends('viewer_friends');
    
 * $this->people_request = new OSPeopleRequest($this->viewer_friends);
 * $this->people_request->addProfileDetails(OSPersonField::PROFILE_URL);
    
 * $data_request = new OSDataRequest('requestInfo');
 * $data_request->addRequest($this->people_request);
    
 * $this->data_response = $data_request->send(true);
 * // this code in the View
 * function <? echo $data_response->getJSFunction()->getName() ?>(<? echo $data_response->getJSFunction()->getArgs() ?>) 
 * {
 *   <?php echo $data_response->getData($people_request); ?>
 *   <?php $person = new OSFriend('person'); ?>
 *   viewer_friends.each(function(<?php echo $person->getVarName() ?>) {
 *   var thumb = <?php echo $person->getField(OSPersonField::THUMBNAIL_URL); ?>
 *   var profile = <?php echo $person->getField(OSPersonField::PROFILE_URL); ?>
 *   html += '<a href="' + profile + '" target="_top" style="float:left">' +
 *     <img src="' + thumb + '"/></a>'; 
 * }
 * </code>
 * @package    opensocial
 * @subpackage datarequest
 * @author     Daniel Botelho <botelho.daniel@gmail.com>
 */
class OSDataRequest
{
  private static $CREATE_DATA_REQUEST_PATTERN = "var %s = opensocial.newDataRequest();\n";
  private static $SEND_DATA_REQUEST_PATTERN = "%s.send(%s);\n\t";

  //PT: nome da variável usada para fazer o request
  /**
   * Variable name used for this DataRequest.
   */
  private $datarequest_var;

  //PT: função JavaScript que vai fazer o request
  /**
   * Request JSFunction
   */
  private $request_func;

  //PT: função JavaScript que vai receber o response
  /**
   * Response JSFunction
   */
  private $response_func;

  //PT: Lista de Pedidos que vão ser feitos ao container
  private /*DataRequestable[]*/ $requestList= array(); 
  
  /**
  * This classe creates an OpenSocial Data Request. The $id will be used to create variable names.
  * @param string The name of this OSDataRequest
  */
  public function __construct($id)
  {
    $this->datarequest_var = $id;
    $this->request_func = new JSFunction($id.'_request');
    $this->response_func = new JSFunction($id.'_response','data');
  }
  
  /**
   * This function should be called after all the request's have been appended to it. This function will return an OSDataResponse that can be used to get in the view to access to the containers response.
   * @param bool If true the generated OSDataRequest will be send to the container.
   * @return OSDataResponse The response object returned by the container.
   */
  public function send($inject = true)
  {
  	if(!$this->getDataRequestFunction()->getContent())
  	  $this->updateDataRequestFunction();
  	if($inject){
  		$ret = JSFunction::addJSTags($this->getDataRequestFunction());
  		echo $ret;
  	}
  	return new OSDataResponse($this);
  }
  
  /**
   * This method allows to append multiple OSDataRequest's 
   * @param OSDataRequest The OSDataRequest that will be appended to this one.
   */
  public function appendDataRequest(OSDataRequest $dataRequest)
  {
  	$this->getDataResponseFunction()->setName($dataRequest->getDataRequestFunction()->getName());
  }
  
  /**
   * Returns the DataRequest variable name.
   * @return string The DataRequest variable name
   */
  public function getDataRequestVarName() { return $this->datarequest_var; }
  
  /**
   * Returns the Request JSFunction
   * @return JSFunction The Request JSFunction
   */
  public function getDataRequestFunction() { return $this->request_func; }
  
  /**
   * Returns the Response JSFunction
   * @return JSFunction The Response JSFunction
   */
  public function getDataResponseFunction() { return $this->response_func; }
  
  /**
   * Returns a list of classes that implements DataRequestable interface
   * @return DataRequestable[] A list of classes that implements DataRequestable
   */
  public function getDataRequestList() { return $this->requestList; }
  
  /**
   * Set the Request JSFunction.
   * @param JSFunction The new Request JSFunction.
   */
  public function setDataRequestFunction(JSFunction $request_func) { $this->request_func = $request_func; }
  
  /**
   * Add's a new OSDataRequestable object to the RequesList.
   * @param OSDataRequestable The new object to be added.
   */
  public function addRequest(OSDataRequestable $dataRequest)
  {
    $this->requestList[] = $dataRequest;
  }
  
  /**
   * This method will update the OSDataRequest Function
   */
  private function updateDataRequestFunction()
  {
  	$request_var = $this->getDataRequestVarName();
 
    // iniciao a variável de request
    $html = sprintf(OSDataRequest::$CREATE_DATA_REQUEST_PATTERN,$request_var);

    // vai buscar a lista de requests's que vão ser executados neste DataRequest
    $requestList = $this->getDataRequestList();
    foreach($requestList as $requestItem) {
      $html .= $requestItem->generateDataRequest($this);
    }
    
    $html .= sprintf(OSDataRequest::$SEND_DATA_REQUEST_PATTERN,$request_var, $this->getDataResponseFunction()->getName());
    
    $js = $this->getDataRequestFunction();
  	$js->setContent($html);
  	$this->setDataRequestFunction( $js );
  }

}
